package com.open.httpauto;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson2.JSONObject;
import com.alibaba.fastjson2.JSONPath;
import com.open.httpauto.http.*;

import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

import static com.alibaba.fastjson2.JSONWriter.Feature.PrettyFormat;

/**
 * 数据格式转化
 */
public enum ConvertHandler {
    Instance;

    /**
     * 转换请求参数
     *
     * @param http
     * @param paramJsonObject
     * @return 转化结果
     */
    public String convertRequest(Http http, JSONObject paramJsonObject) {
        Context context = http.getContext();
        HttpDataType httpDataType = HttpDataType.getEnum(context.getDataType());
        List<RequestParameter> requestMap = this.init(http.getRequest(), context);
        DigestEnum digestEnum = DigestEnum.getEnum(context.getDigest());
        IDigestHandler iDigestHandler = new SimpleDigestHandler();


        String text = null;
        if (HttpDataType.JSON == httpDataType) {
            JSONObject jsonObject = this.convertJson(requestMap, paramJsonObject, context);
            //数据加密或者签名
            if (DigestEnum.AES == digestEnum) {
                text = iDigestHandler.aesEncrypt(jsonObject.toJSONString(), context);
            } else if (DigestEnum.MD5 == digestEnum) {
                String sign = iDigestHandler.md5Sign(requestMap, jsonObject, context);

                Map<String, String> map = requestMap.stream()
                        .collect(Collectors.toMap(RequestParameter::getProperty, RequestParameter::getParameter));
                String signParameter = map.get(ParameterBase.Property.Sign.property);

                jsonObject.put(signParameter, sign);
                text = jsonObject.toJSONString(PrettyFormat);
            }
        } else if (HttpDataType.FORM == httpDataType || HttpDataType.QUERY == httpDataType) {
            text = this.convertPlain(requestMap, paramJsonObject, context);
            //数据加密或者签名
//            if (DigestEnum.AES == digestEnum) {
//                text = DigestHandler.Instance.aesEncrypt(text, context);
//            } else if (DigestEnum.MD5 == digestEnum) {
//                String sign = DigestHandler.Instance.md5Sign(requestMap, context);
//                String signKey = context.getSignKey();
//                jsonObject.put(signKey, sign);
//                text = jsonObject.toJSONString(PrettyFormat);
//            }
        }

        return text;
    }

    /**
     * 初始化请求参数默认值
     *
     * @param requestParameterList 请求参数映射集合
     * @param context              全局参数
     * @return 设置完成默认值请求参数映射集合
     */
    private List<RequestParameter> init(List<RequestParameter> requestParameterList, Context context) {
        if (CollectionUtil.isEmpty(requestParameterList)) {
            return requestParameterList;
        }

        for (RequestParameter requestParameter : requestParameterList) {
            //初始化appid默认值
            if (ParameterBase.Property.Appid.property.equalsIgnoreCase(requestParameter.getProperty())) {
                requestParameter.setDefaultValue(context.getAppId());
            }
            //初始化时间戳默认值
            if (ParameterBase.Property.Timestamp.property.equalsIgnoreCase(requestParameter.getProperty())) {
                Long timestamp = TimestampEnum.getEnum(context.getTimestamp()).getTime();
                requestParameter.setDefaultValue(String.valueOf(timestamp));
            }
            //初始化随机数
            if (ParameterBase.Property.Nonce.property.equalsIgnoreCase(requestParameter.getProperty())) {
                requestParameter.setDefaultValue(RandomUtil.randomString(16));
            }
        }

        return requestParameterList;
    }

    /**
     * 转化请求后响应结果
     *
     * @param json                  请求结果json字符串
     * @param responseParameterList 响应参数配置映射集合
     * @return
     */
    public JSONObject convertResponse(String json, List<ResponseParameter> responseParameterList) {
        try {
            if (json.startsWith("{") && json.endsWith("}")) {
                JSONObject responseJson = new JSONObject();
                for (ResponseParameter responseParameter : responseParameterList) {
                    //通过json path 算法 遍历指定属性的值
                    List<Object> objList = (List<Object>) JSONPath.eval(json, "$.." + responseParameter.getParameter());
                    String data = null;
                    if (CollectionUtil.isNotEmpty(objList)) {
                        data = String.valueOf(objList.get(0));
                    } else if (CollectionUtil.isEmpty(objList) && !StrUtil.isBlank(responseParameter.getDefaultValue())) {
                        data = responseParameter.getDefaultValue();
                    } else {
                        continue;
                    }

                    //设置标准属性
                    responseJson.put(responseParameter.getProperty(), data);
                }

                return responseJson;
            } else {
                return null;
            }

        } catch (Exception e) {
            e.printStackTrace();
        }

        return null;
    }

    private String convertPlain(List<RequestParameter> requestMap, JSONObject paramJsonObject, Context context) {
        return null;
    }

    /**
     * 转换数据为json 格式
     */
    private JSONObject convertJson(List<RequestParameter> requestMap, JSONObject paramJsonObject, Context context) {
        //请求映射转化
        JSONObject jsonObject = new JSONObject();
        for (RequestParameter requestParameter : requestMap) {
            Object value = paramJsonObject.get(requestParameter.getProperty());
            if (Objects.isNull(value) && StrUtil.isNotBlank(requestParameter.getDefaultValue())) {
                value = requestParameter.getDefaultValue();
            }

            if (StrUtil.isNotBlank(requestParameter.getDataType())) {
                if (requestParameter.getDataType().equalsIgnoreCase(Integer.class.getSimpleName())) {
                    jsonObject.put(requestParameter.getParameter(), Integer.parseInt(String.valueOf(value)));
                } else if (requestParameter.getDataType().equalsIgnoreCase(Double.class.getSimpleName())) {
                    jsonObject.put(requestParameter.getParameter(), Double.parseDouble(String.valueOf(value)));
                } else if (requestParameter.getDataType().equalsIgnoreCase(Float.class.getSimpleName())) {
                    jsonObject.put(requestParameter.getParameter(), Float.parseFloat(String.valueOf(value)));
                }
            } else {
                jsonObject.put(requestParameter.getParameter(), value);
            }
        }
        return jsonObject;
    }
}
